package org.wenhua.yuan.uilib

import android.content.Context
import android.util.Log
import android.util.SparseArray
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import androidx.recyclerview.widget.RecyclerView.Adapter
import java.lang.reflect.ParameterizedType
import java.util.*

class UIAdapter(val context: Context) : Adapter<ViewHolder>() {
    // 使用ArrayList，包含RecyclerView列表item泛型数据结构UIDataItem（数据模型和ViewHolder）
    private var dataSets = ArrayList<UIDataItem<*, ViewHolder>>()
    // 使用SparseArray 下标：view类型Int值，value是UIDataItem
    private var typeArrays = SparseArray<UIDataItem<*, ViewHolder>>()


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        var viewItem = typeArrays.get(viewType)
        // 获取viewItem对应的视图
        var view = viewItem.getItemView(parent)
        if (view == null) {
            val resLayout = viewItem.getItemResource()
            if (resLayout < 0) {
                RuntimeException("应该先要去复写 getItemView or getItemLayoutRes")
            }
            view = LayoutInflater.from(context).inflate(resLayout, parent, false)
        }

        return createViewHolderInternal(viewItem::class.java, view)

    }

    private fun createViewHolderInternal(javaClass: Class<out UIDataItem<*, ViewHolder>>, view: View?): ViewHolder {
        try {
            val superCls = javaClass.genericSuperclass
            if (superCls is ParameterizedType) {
                // 获取泛型的参数集合
                val arguments = superCls.actualTypeArguments
                for (argument in arguments) {
                    if (argument is Class<*> && ViewHolder::class.java.isAssignableFrom(argument as Class<*>)) {
                        // 反射获取viewHolder对象(fixed：原先这里报错，通过调试发现写成了View!!::class.java)
                        return argument.getConstructor(view!!::class.java).newInstance() as ViewHolder
                    }
                }
            }
        } catch (e:Exception) {
            Log.e("UIAdapter err::", e.toString())
        }

        return object : ViewHolder(view!!){}

    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

        val viewItem = dataSets[position]
        // 把当前数据(position, holder)回调到相应子UIDataItem中
        // 将数据的绑定实现放在各自不同的子Item数据绑定中
        /** 使用用例：
           class OneExample(data: ItemData) : UIDataItem<ItemData, RecyclerView.ViewHolder>(data) {
                override fun onBindViewHolderInChild(holder: RecyclerView.ViewHolder, position: Int) {
                    holder.itemView.findViewById<ImageView>(R.id.item_image).setImageResource(R.drawable.item_banner)
                }
                override fun getItemLayoutRes(): Int {
                    return R.layout.layout_list_item_banner
                }
            }
         */
        viewItem.onBindViewHolderInChild(position, holder)
    }

    override fun getItemViewType(position: Int): Int {
        val viewItem = dataSets.get(position)
        val type = viewItem::class.java.hashCode()
        if (typeArrays.indexOfKey(type) < 0) {
            typeArrays.put(type, viewItem)
        }
        return type
    }

    override fun getItemCount(): Int {

        return dataSets?.let {it.size}
    }


    /**
     * 移除指定item
     */
    fun removeListItem(dataItem: UIDataItem<*, ViewHolder>) {
        val index: Int = dataSets.indexOf(dataItem)
        removeListItemAt(index)
    }

    /**
     * 指定刷新 某个item的数据
     */
    fun refreshListItem(dataItem: UIDataItem<*, ViewHolder>) {
        val indexOf = dataSets.indexOf(dataItem)
        notifyItemChanged(indexOf)
    }
    /**
     * 从指定位置上移除item
     */
    fun removeListItemAt(index: Int): UIDataItem<*, out ViewHolder>? {
        if (index >= 0 && index < dataSets.size) {
            val remove: UIDataItem<*, out ViewHolder> = dataSets.removeAt(index)
            notifyItemRemoved(index)
            return remove
        } else {
            return null
        }
    }

    fun addItems(items: List<UIDataItem<*, ViewHolder>>, notify: Boolean) {
        val start = dataSets.size
        for (item in items) {
            dataSets.add(item)
        }
        if (notify) {
            notifyItemRangeInserted(start, items.size)
        }
    }

}